use rand::{prelude::*, rngs::OsRng};
use rand_pcg::Pcg64Mcg;

pub fn choose_by_weight<T>(rng: &mut impl Rng, iter: impl Iterator<Item = (T, f64)>) -> Option<T> {
    iter.filter(|(_, p)| *p > 0.0)
        .reduce(|(selected, p_acc), (x, p)| {
            let p_acc = p_acc + p;
            let selected = if rng.gen_bool(p / p_acc) { x } else { selected };
            (selected, p_acc)
        })
        .map(|(x, _)| x)
}

pub fn make_rng() -> Pcg64Mcg {
    Pcg64Mcg::from_rng(OsRng).expect("RNG生成失败")
}
